home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-03-23 | 83.5 KB | 2,285 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------//
- // CoreSample - An application that is Apple Event-aware, Scripting Compatible, //
- // and recordable. It supports the Required and Core Suite of //
- // Apple Events, the Object Model, and the Open Scripting //
- // Architecture. //
- // //
- // by: Sue Dumont //
- // Applications Scripting Group //
- // //
- // Copyright © Apple Computer, Inc. 1991,1992 //
- // All rights reserved. //
- // //
- // SimpleSample 1/1/92 //
- // Version 1.0d6 5/8/92 //
- // Version 1.0.1 11/23/92 //
- // Version 1.0.2 4/2/93 //
- // Version 1.1 12/1/93 //
- // //
- // //
- // NOTE: This application conforms to the "Apple Event Registry, Standard Suites //
- // Winter 1992, Vers. 1.0". // //
- // //
- // The main purpose of this sample code is to demonstrate how to develop an //
- // application that is Apple event-aware, scripting compatible, uses the Object //
- // Support Library, and supports Apple's Open Scripting Architecture. In //
- // addition, it has its own 'aete' (Apple Event Terminology Extension) resource //
- // (CoreSampleAETE.r). By incorporating these technologies into your application, //
- // your application will support Apple's Open Scripting Architecture. //
- // //
- // The functionality of CoreSample is basic window manipulation. The user may //
- // create, drag, size, zoom, and close windows. All these actions may be //
- // performed through Apple events. //
- // //
- // This application is also "factored", which means that user interactions (such //
- // as dragging or sizing a window, selecting a menuitem) are converted into Apple //
- // events which the application sends off to itself, and then is handled by the //
- // corresponding event handler. Factoring makes it possible to access the appli- //
- // cation's functionality through Apple events. It also makes it easier to record //
- // the user's actions in the form of Apple events. //
- // //
- // CoreSample supports the Required and Core suites of events, and the application //
- // and window object classes. One additional property has been added to the window //
- // class, and that is its position, the top left-hand coordinates of the window. //
- // Some events only apply to the window class, such as Create, Move, Clone, and //
- // Set Data (application properties are not modifiable, except for pClipboard, //
- // which I do not support). Currently, CoreSample supports the Simple Grammar, //
- // as defined in the "Object Support Library Developer Note". //
- // //
- // The properties you may access with the Get Data Apple event are as follows: //
- // Application - Best Type, Default Type, Class, Name, IsFrontProcess, Version //
- // Window - Best Type, Default Type, Bounds, Class, Index, Name, Position, //
- // Closeable, Titled, Resizable, Zoomable, Floating, Modal, Zoomed, //
- // and Visible. //
- // The properties you may set with the Set Data Apple event are as follows: //
- // Window - Bounds, Index, Zoomed, Name, Position, and Visible. //
- // //
- // When you create a new element, you may pass it initial data values. This //
- // application will create the new element accordingly if either or both of the //
- // initial data parameters exist. In addition, with CoreSample, you may create or //
- // move a window without passing it an insertion location record. By default, a //
- // window will be created/moved to the frontmost position. //
- // //
- // (NOTE: Some portions of this code are derived from TESample, a //
- // sample application provided by Apple Developer Technical Support.) //
- // //
- // //
- // Modification History: //
- // 11/91 <smd> - Initial code implementation. //
- // 01/06/92 <kc> - Added code for Count Elements, Do Objects Exist, Move, //
- // and Get Data Size. //
- // 01/09/92 <kc> - Quick clean up for Scripting QuickStart. //
- // 01/10/92 <smd> - Made insertion location parameter optional in the Create //
- // and Move events, and provided my own default behavior. //
- // 01/21/92 <smd> - Positive and negative offset when referencing by index. //
- // 01/30/92 <smd> - Adding complete support for core suite and properties. //
- // 02/05/92 <smd> - Handling optional parameters in Create Element event. //
- // 02/17/92 <smd> - Added InitializeDescs() and DisposeDescs() routines. //
- // 02/21/92 <smd> - Fixed bug where the same AEDesc was being passed as source //
- // and dest to AECoerceDesc(). //
- // - Send myself a Move event when user clicks in content of a //
- // window. //
- // 02/24/92 <smd> - Now sends a Move event when just making a window active. //
- // This is done in the DoEvent routine, drag region. //
- // 02/25/92 <smd> - Modified GetWindowWithTitle, GetWidnowWithIndex, and //
- // GetWindowIndexNum routines to use WindowList so ALL windows //
- // will be accessed (even invisible ones). //
- // - Changed InitializeDescs to MyInitDescs and DisposeDescs to //
- // MyDisposeDescs. //
- // - Removed the FailIfErr calls from the AE Handlers so that //
- // they will return the error code rather than dying. //
- // 02/28/92 <smd> - Added coercion routines (thanks Kevin) to clean up code. //
- // These convert from descs to boolean, long, and pstrings. //
- // 04/20/92 <smd> - Fixed a bug with setting the visibility property of a window.//
- // 04/27/92 <smd> - Fixed bug in DoSetData where data was set to a pointer, and //
- // then the pointer was diposed of. //
- // 04/30/92 <smd> - Check if replacing the same window in HandleMove //
- // (i.e., "move window 2 to window 2"). If so, do nothing. //
- // 06/25/92 <smd> - Changed FindRelativeWindow to return the windowPtr of the //
- // window being replaced rather than closing it. This caused //
- // an error when trying to replace the same window, in which //
- // case nothing should happen. (Ex. move window 2 to window 2).//
- // 07/19/92 <smd> - Fixed bug where the Move event was not recording the //
- // correct window being moved when the data was being passed //
- // by index rather than by name. //
- // 10/01/92 <smd> - Added pVersion to application and now set the port before //
- // setting the pPosition property. //
- // 4/02.93 <smd> - added GetWindowBounds routine to calculate the correct //
- // bounds when the bounds accessed from the content region is //
- // invalid (such as when the application is hidden). //
- // - cleaned up the aete. //
- // 6/22/93 <doo> - converted files to run in the Think C 6.0 environment //
- // Fixed incorrect comparison of rects and windowlist problems //
- // associated with the Think compiler. //
- // 12/1/93 <dan> - added PowerPC support - will run native on PowerPC if //
- // compiled on PowerPC system. These changes are denoted //
- // by [pwpc]. //
- //----------------------------------------------------------------------------------//
- #include <SysEqu.h> // To use WindowList.
- #include <Types.h>
- #include <Quickdraw.h>
- #include <Events.h>
- #include <AppleEvents.h>
- #include <AEObjects.h>
- #include <AEPackObject.h>
- #include <Resources.h> // for version resource
- #include <Windows.h>
- #include <Menus.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <Scrap.h>
- #include <limits.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <OSUtils.h>
- #include <OSEvents.h>
- #include <DiskInit.h>
- #include <Packages.h>
- #include <Traps.h>
- #include <string.h>
- #include <Strings.h>
- #include <stdarg.h>
- #include "AERegistry.h" // Constants defined in the Registry.
- #include "CoreSample.h"
-
- #define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
- #define LoWrd(aLong) ((aLong) & 0xFFFF)
-
- typedef long* LongPtr;
- typedef WindowPeek* PeekPtr;
-
- // Globals.
- SysEnvRec gMac; // Contains the system environment
- Boolean gHasWaitNextEvent; // True if WaitNextEvent trap is available
- Boolean gInBackground; // Determines if currently in the background
- long gNumWindowsOpen; // The number of windows open
- short gNewWindows; // The number of new windows created
- Boolean gQuitApp; // True to quit the application
- AEDesc gNullDesc; // A null descriptor record
- AEAddressDesc gSelfAddress; // A self-addressed address descriptor record
- ProcessSerialNumber gSelfPSN; // This application's psn
- short gRefNum; // reference number of rescource file
-
- #if powerc // [pwpc]
- QDGlobals qd;
- #endif
-
- //----------------------------------------------------------------------------------//
- // PROTOTYPES //
- //----------------------------------------------------------------------------------//
- void AdjustMenuStates(void);
- void AlertUser(short error);
- void CloseTheWindow(WindowPtr window);
- WindowPtr CreateNewWindow(WindowPtr behind);
- OSErr CreateWindowObjectSpec(WindowPtr window,short formType,AEDesc *objectSpec);
- void DoEvent(EventRecord *event);
- void DoGrowWindow(WindowPtr window, EventRecord *event);
- void DoMenuCommand(long menuResult);
- OSErr DoSetData(AEDesc *token, AEDesc *data);
- void DoUpdate(WindowPtr window);
- void EventLoop(void);
- void FailIfErr(OSErr error);
- OSErr FindRelativeWindow(WindowPtr *window,AEDesc *object,DescType pos,WindowPtr *replaceWindow);
- OSErr GetAppData(DescType theProperty, AEDesc *result);
- OSErr GetMissingParams(AppleEvent *theAppleEvent);
- OSErr GetWindowData(DescType property, WindowPtr window, AEDesc *result);
- long GetWindowIndexNum(WindowPtr window);
- WindowPtr GetWindowAtIndex(long index);
- WindowPtr GetWindowWithTitle(ConstStr255Param title);
- void InitAEHandlers(void);
- void Initialize(void);
- Boolean IsAppWindow(WindowPtr window);
- Boolean IsDAWindow(WindowPtr window);
- Boolean IsTrapAvailable(short tNumber, TrapType tType);
- void ReportError(AppleEvent *reply, long err);
- WindowPtr ResolveToWindow(AEDesc *objectSpecifier);
- void SendClose(WindowPtr window);
- void SendCreateElement(void);
- void SendMoveEvent(WindowPtr windowToMove, long index);
- void SendQuitApp(void);
- void SendSetData(AEDesc *pDesc, AEDesc *pData, AEDesc *object);
- void SetUpPropertyData(WindowPtr window,DescType propType,DescType dataType,Size dataSize);
- void SignalError(short error);
- void Terminate(void);
- void ZoomIt(WindowPtr window, short part);
- Rect GetWindowBounds(WindowPtr window);
-
- extern pascal OSErr CreateObjSpecifier(DescType theClass, AEDesc *theContainer,
- DescType keyForm, AEDesc *keyData, Boolean disposeInputs,
- AEDesc *objSpecifier);
- extern void _DataInit();
-
-
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- main()
- {
- #ifndef THINK_C
- UnloadSeg((Ptr) _DataInit); // Note that _DataInit must not be in Main!
- #endif
-
- MaxApplZone(); // Expand the heap so code segments load at the top.
- Initialize(); // Initialize the program
-
- #ifndef THINK_C // Initialize the program
- UnloadSeg((Ptr)Initialize); // Note that Initialize must not be in Main!
- #endif
-
- EventLoop(); // Call the main event loop
- }
-
- //----------------------------------------------------------------------------------//
- // Continue retrieving events until the application terminates. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void EventLoop()
- {
- RgnHandle cursorRgn;
- Boolean gotEvent;
- EventRecord event;
-
- cursorRgn = NewRgn();
- gQuitApp = false; // This is set to true in Terminate().
-
- while (!gQuitApp) // Loop until user quits or error.
- {
- if (gHasWaitNextEvent)
- gotEvent = WaitNextEvent(everyEvent, &event, LONG_MAX, cursorRgn);
- else
- {
- SystemTask();
- gotEvent = GetNextEvent(everyEvent, &event);
- }
- if (gotEvent)
- DoEvent(&event);
- }
- }
-
- //----------------------------------------------------------------------------------//
- // Find out which event this is and send it off to its appropriate handler. //
- // When the user clicks in the drag region, either one of two events may be //
- // triggered. The set position property (set data event) would occur if the widnow //
- // is dragged to another location, or the move event would be sent if the window //
- // is just made active. In the latter case, the window's index before being //
- // moved to the front is passed to SendMoveEvent for recording purposes. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void DoEvent( EventRecord* event )
- {
- long index=0;
- short part, err;
- WindowPtr window;
- char key;
- Rect bounds1, bounds2;
- Point aPoint;
-
- switch (event->what)
- {
- case mouseDown:
- part = FindWindow(event->where, &window);
- switch (part)
- {
- case inMenuBar:
- AdjustMenuStates();
- DoMenuCommand(MenuSelect(event->where));
- break;
-
- case inSysWindow:
- SystemClick(event, window);
- break;
-
- case inContent:
- if (window != FrontWindow())
- SendMoveEvent(window, index);
- break;
-
- case inDrag:
- index = GetWindowIndexNum(window);
- bounds1 = (*((WindowPeek)window)->contRgn)->rgnBBox;
- DragWindow(window, event->where, &qd.screenBits.bounds);
- bounds2 = (*((WindowPeek)window)->contRgn)->rgnBBox;
- if ((bounds1.left == bounds2.left) &&
- (bounds1.top == bounds2.top))
- SendMoveEvent(GetWindowAtIndex(index), index);
- else
- SetUpPropertyData(window,pPosition,typeQDPoint,sizeof(Point));
- break;
-
- case inGoAway:
- if (TrackGoAway(window, event->where))
- SendClose(window);
- break;
-
- case inGrow:
- DoGrowWindow(window, event);
- break;
-
- case inZoomIn: // For recording purposes, we send an Apple
- case inZoomOut: // event to ourselves to set the bounds property.
- if (TrackBox(window, event->where, part))
- {
- ZoomIt(window, part);
- SetUpPropertyData(window, pIsZoomed, typeBoolean, sizeof(Boolean));
- }
- break;
- }
- break;
-
- case keyDown:
- case autoKey: // Only handle menu key equivalents
- key = event->message & charCodeMask;
- if (event->modifiers & cmdKey) // Command key down
- {
- if (event->what == keyDown)
- {
- AdjustMenuStates(); // Enable/disable/check menu items properly
- DoMenuCommand(MenuKey(key));
- }
- }
- break;
-
- case activateEvt:
- DrawGrowIcon((WindowPtr)event->message);
- break;
-
- case updateEvt:
- DoUpdate((WindowPtr) event->message);
- break;
-
- case diskEvt:
- if (HiWord(event->message) != noErr)
- {
- SetPt(&aPoint, kDILeft, kDITop);
- err = DIBadMount(aPoint, event->message);
- }
- break;
-
- case kOSEvent:
- {
- switch ((event->message >> 24) & 0x0FF) // High byte of message.
- {
- case kMouseMovedMessage:
- break; // Do nothing if mouse moved.
-
- case kSuspendResumeMessage: // suspend/resume is also an activate/deactivate
- SetCursor(&qd.arrow);
- if (IsAppWindow(window = FrontWindow()))
- DrawGrowIcon(window);
- break;
- }
- }
- break;
-
- case kHighLevelEvent: // Let the Apple Event Manager handle high level event.
- AEProcessAppleEvent(event);
- break;
-
- default:
- break;
- }
- }
-
- //----------------------------------------------------------------------------------//
- // Handle the mouseDown event in the grow box region of the window. If the //
- // window has been resized, an Apple Event is sent to set the bounds property. //
- // This is done for recording purposes. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void DoGrowWindow( WindowPtr window,
- EventRecord* event )
- {
- long result;
- Rect tempRect;
-
- tempRect = qd.screenBits.bounds; // Set up the limiting values.
- tempRect.top = kMinWinDim;
- tempRect.left = kMinWinDim;
- result = GrowWindow(window, event->where, &tempRect);
- if (result) // Did window actually change size?
- {
- SetPort(window);
- InvalRect(&window->portRect);
- SizeWindow(window, LoWrd(result), HiWrd(result), true);
- InvalRect(&window->portRect); // Send event for recording purposes.
- SetUpPropertyData(window, pBounds, typeQDRectangle, sizeof(Rect));
- }
- }
-
- //----------------------------------------------------------------------------------//
- // Zoom the window and set the refcon field to reflect its zoomed state. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void ZoomIt( WindowPtr window,
- short part )
- {
- SetPort(window);
- EraseRect(&window->portRect); // We just have a blank window.
- ZoomWindow(window, part, window == FrontWindow());
- SetWRefCon(window, (long)part == inZoomOut); // Set to true if zoomed.
- InvalRect(&window->portRect);
- }
-
- //----------------------------------------------------------------------------------//
- // This is called when an update event is received for a window. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void DoUpdate( WindowPtr window )
- {
- if (IsAppWindow(window))
- {
- BeginUpdate(window);
- SetPort(window);
- EraseRect(&window->portRect); // We just have an empty window.
- DrawGrowIcon(window);
- EndUpdate(window);
- }
- }
-
- //----------------------------------------------------------------------------------//
- // Set up the menus according to the current state. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void AdjustMenuStates()
- {
- WindowPtr window;
- MenuHandle menu;
-
- window = FrontWindow();
- menu = GetMHandle(mFile);
- if (gNumWindowsOpen < kMaxOpenWindows)
- EnableItem(menu, iNew); // Enable New if we can open more windows.
- else
- DisableItem(menu, iNew);
- if (window)
- EnableItem(menu, iClose); // Enable Close if there is a window to close.
- else
- DisableItem(menu, iClose);
- }
-
- //----------------------------------------------------------------------------------//
- // This is called when an item is chosen from the menu bar. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void DoMenuCommand(long menuResult)
- {
- short menuID, menuItem;
- short itemHit, daRefNum;
- Str255 daName;
- WindowPtr window;
-
- window = FrontWindow();
- menuID = HiWord(menuResult);
- menuItem = LoWord(menuResult);
- switch (menuID)
- {
- case mApple:
- switch (menuItem)
- {
- case iAbout:
- itemHit = Alert(rAboutAlert, nil);
- break;
- default: // all other items in this menu are DA's.
- GetItem(GetMHandle(mApple), menuItem, daName);
- daRefNum = OpenDeskAcc(daName);
- break;
- }
- break;
-
- case mFile:
- switch (menuItem) // All these items send Apple events to
- { // handle the selection.
- case iNew:
- SendCreateElement();
- break;
- case iClose:
- SendClose(FrontWindow());
- break;
- case iQuit:
- SendQuitApp();
- break;
- }
- break;
-
- case mEdit: // Call SystemEdit for DA editing & MultiFinder.
- SystemEdit(menuItem-1);
- break;
- }
- HiliteMenu(0); // Unhighlight what MenuSelect (or MenuKey) hilited.
- }
-
- //----------------------------------------------------------------------------------//
- // This routine appends the ascii representation of num to the title string. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void MakeNewWindowTitle( short num, // Window number.
- Str255 title) // Window title.
- {
- short i, count, index;
- char numStr[5];
-
- i = 0;
- do {
- numStr[i++] = num % 10 + '0';
- } while (num /= 10);
-
- index = title[0] + 1; // Get length of title string.
-
- for (count = i-1; count >= 0; count--)
- title[index++] = numStr[count];
- title[0] += i;
- }
-
- //----------------------------------------------------------------------------------//
- // Create a new window behind the given window. Use the window's refCon //
- // field to indicate whether the window is zoomed or not. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- WindowPtr CreateNewWindow(WindowPtr behindWindow)
- {
- Ptr storage;
- WindowPtr newWindow, firstWindow;
- Rect bounds;
- Str255 title;
-
- if (gNumWindowsOpen < kMaxOpenWindows)
- {
- storage = NewPtr(sizeof(WindowRecord));
- if (storage != nil)
- {
- newWindow = GetNewWindow(rDocWindow, storage, behindWindow);
- if (newWindow != nil)
- {
- gNumWindowsOpen++; // Increment the number of windows currently open.
- gNewWindows++; // Increment the number of new windows created.
- GetWTitle(newWindow, title);
- MakeNewWindowTitle(gNewWindows, title);
- SetWTitle(newWindow, title);
- if (firstWindow = FrontWindow())
- {
- //••• bounds = (*((WindowPeek)firstWindow)->contRgn)->rgnBBox;
- bounds = GetWindowBounds(firstWindow);
- MoveWindow(newWindow, bounds.left+30, bounds.top+30, false);
- }
- SetWRefCon(newWindow, 0L); // set zoom state to false.
- SetPort(newWindow);
- return(newWindow);
- }
- else
- DisposPtr(storage); // Dispose of the storage if it is not used.
- }
- }
- return(nil);
- }
-
- //----------------------------------------------------------------------------------//
- // Close the given window or desk accessory. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void CloseTheWindow(WindowPtr window)
- {
- if (IsDAWindow(window))
- CloseDeskAcc(((WindowPeek)window)->windowKind);
- else
- if (IsAppWindow(window))
- {
- CloseWindow(window);
- DisposPtr((Ptr)window);
- gNumWindowsOpen--;
- }
- }
-
- //----------------------------------------------------------------------------------//
- // Returns true if the window belongs to this application, else false. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- Boolean IsAppWindow(WindowPtr window)
- {
- if (!window)
- return(false);
- else
- return(((WindowPeek)window)->windowKind == userKind);
- }
-
- //----------------------------------------------------------------------------------//
- // Returns true if the given window belongs to a DA, else false is returned. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- Boolean IsDAWindow(WindowPtr window)
- {
- if (window == nil)
- return(false);
- else // DA windows have negative windowKinds.
- return(((WindowPeek)window)->windowKind < 0);
- }
-
- //----------------------------------------------------------------------------------//
- // If an error has occurred, I check the user interaction level. If I can //
- // interact with the user, I put up a dialog and exit the application; otherwise, //
- // I just exit the application. //
- // //
- // ***NOTE: Real applications would not handle errors in this fashion! If they //
- // cannot interact with the user, they should abort the Apple event handler and //
- // return the error in the reply parameter. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void FailIfErr(OSErr error)
- {
- if (error)
- {
- if (!(AEInteractWithUser(kNoTimeOut, nil, nil))) // Can we interact?
- AlertUser(eAEError); // Yes, so put up the dialog.
- ExitToShell();
- }
- }
-
- //----------------------------------------------------------------------------------//
- // Display an alert for the user to indicate that an error has occurred. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void AlertUser(short error)
- {
- short itemHit;
- Str255 message;
-
- GetIndString(message, kErrStrings, error);
- ParamText(message, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p"); // [pwpc]
- itemHit = Alert(rUserAlert, nil);
- }
-
- //----------------------------------------------------------------------------------//
- // Quit the application by closing all windows and setting the quit flag to true. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void Terminate()
- {
- WindowPtr aWindow;
-
- while(aWindow = FrontWindow())
- CloseTheWindow(aWindow);
- AEDisposeDesc(&gSelfAddress); // Dispose of my self-addressed descriptor.
- gQuitApp = true;
- }
-
- //----------------------------------------------------------------------------------//
- // Perform the initialization necessary at start-up time. Note that we use //
- // kCurrentProcess in our psn rather than calling GetCurrentProcess. Using //
- // kCurrentProcess will allow us to record those events we send to ourselves, //
- // otherwise, the recorder won't recognize the psn and won't record our event! //
- //----------------------------------------------------------------------------------//
- #pragma segment Initialize
- void Initialize()
- {
- Handle menuBar;
- long total, contig;
- EventRecord event;
- short count;
-
- gInBackground = false;
- InitGraf((Ptr)&qd.thePort);
- InitWindows();
- InitMenus();
- InitDialogs(nil);
- InitCursor();
- InitAEHandlers();
- for (count = 1; count <= 3; count++)
- EventAvail(everyEvent, &event);
-
- SysEnvirons(kSysEnvironsVersion, &gMac);
- if (gMac.machineType < 0)
- SignalError(eWrongMachine); // Less than 128K ROM's.
- gHasWaitNextEvent = IsTrapAvailable(_WaitNextEvent, ToolTrap);
-
- if ((long)GetApplLimit() - (long)ApplicZone() < kMinHeap)
- SignalError(eSmallSize);
-
- PurgeSpace(&total, &contig);
- if (total < kMinSpace)
- if (UnloadScrap() != noErr)
- SignalError(eNoMemory);
- else
- {
- PurgeSpace(&total, &contig);
- if (total < kMinSpace)
- SignalError(eNoMemory);
- }
-
- if (!(menuBar = GetNewMBar(rMenuBar))) // Set up menu bar.
- SignalError(eNoMemory);
- SetMenuBar(menuBar);
- DisposHandle(menuBar);
- AddResMenu(GetMHandle(mApple), 'DRVR'); // Add DA's to menu.
- DrawMenuBar();
-
- // Set up the self-addressed descriptor record.
- gSelfPSN.highLongOfPSN = 0;
- gSelfPSN.lowLongOfPSN = kCurrentProcess; //* Use this instead of GetCurrentProcess *//
- FailIfErr(AECreateDesc(typeProcessSerialNumber,(Ptr)&gSelfPSN,sizeof(ProcessSerialNumber),&gSelfAddress));
- gNullDesc.descriptorType = typeNull; // Initialize the global null descriptor record.
- gNullDesc.dataHandle = nil;
-
- gRefNum = CurResFile();
- gNumWindowsOpen = 0;
- gNewWindows = 0;
- }
-
- //----------------------------------------------------------------------------------//
- // Returns true if the given trap number is implemented, else returns false. //
- //----------------------------------------------------------------------------------//
- #pragma segment Initialize
- Boolean IsTrapAvailable(short trapNum, TrapType tType)
- {
- if ((tType == (unsigned char)ToolTrap) && (gMac.machineType > envMachUnknown) &&
- (gMac.machineType < envMacII))
- { // it's a 512K, Plus, or SE
- trapNum = trapNum & 0x03FF;
- if (trapNum > 0x01FF) // which means the tool traps
- trapNum = _Unimplemented; // only go to 0x01FF
- }
- return(NGetTrapAddress(trapNum, tType) != GetToolTrapAddress(_Unimplemented)); // [pwpc]
- }
-
- //----------------------------------------------------------------------------------//
- #pragma segment Initialize
- void SignalError(short error)
- {
- AlertUser(error);
- ExitToShell();
- }
-
- //**********************************************************************************//
- // * Apple Events and Object Model Support * //
- //**********************************************************************************//
-
- //----------------------------------------------------------------------------------//
- // Initializes all descriptor records passed in to this routine. The variable //
- // argument list is null terminated. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void MyInitDescs(AEDesc* desc1, ... ) // Variable, null terminated argument list.
- {
- va_list argptr; // pointer to each argument in list.
- AEDesc* nextDesc; // next descriptor argument in list.
-
- va_start(argptr, desc1);
- desc1->descriptorType = typeNull;
- desc1->dataHandle = nil;
-
- while(nextDesc = va_arg(argptr, AEDesc *))
- {
- nextDesc->descriptorType = typeNull;
- nextDesc->dataHandle = nil;
- }
- va_end(argptr);
- }
-
- //----------------------------------------------------------------------------------//
- // Dispose all descriptor records passed into this routine. (Variable arg. list). //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void MyDisposeDescs(AEDesc* desc1, ... ) // Null terminated argument list.
- {
- va_list argptr; // pointer to each argument in list.
- AEDesc* nextDesc; // descriptor argument in list.
-
- va_start(argptr, desc1);
- if (desc1->dataHandle)
- AEDisposeDesc(desc1);
-
- while(nextDesc = va_arg(argptr, AEDesc *))
- {
- if (nextDesc->dataHandle)
- AEDisposeDesc(nextDesc);
- }
- va_end(argptr);
- }
-
- //----------------------------------------------------------------------------------//
- // Converts a descriptor to a boolean. //
- //----------------------------------------------------------------------------------//
- #pragma segment AppleEvents
- OSErr DescToBoolean(const AEDesc* desc, Boolean* boolvalue)
- {
- AEDesc tempDesc;
- Handle dataHandle;
-
- tempDesc.dataHandle = nil;
- if (desc->descriptorType == typeBoolean)
- dataHandle = desc->dataHandle;
- else
- if (AECoerceDesc(desc, typeBoolean, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return(errAECoercionFail);
-
- *boolvalue = **dataHandle;
- MyDisposeDescs(&tempDesc, kEndOfList);
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------//
- // Converts a descriptor to a long. //
- //----------------------------------------------------------------------------------//
- #pragma segment AppleEvents
- OSErr DescToLong(const AEDesc* desc, long* longvalue)
- {
- AEDesc tempDesc;
- Handle dataHandle;
-
- tempDesc.dataHandle = nil;
- if (desc->descriptorType == typeLongInteger)
- dataHandle = desc->dataHandle;
- else
- if (AECoerceDesc(desc, typeLongInteger, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return(errAECoercionFail);
-
- *longvalue = *(LongPtr)*dataHandle;
- MyDisposeDescs(&tempDesc, kEndOfList);
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------//
- // Converts a descriptor to a pascal string. //
- //----------------------------------------------------------------------------------//
- #pragma segment AppleEvents
- OSErr DescToPString(const AEDesc* desc, Str255 str, short maxLength)
- {
- AEDesc tempDesc;
- Handle dataHandle;
- long charCount;
-
- tempDesc.dataHandle = nil;
- if (desc->descriptorType == typeChar)
- dataHandle = desc->dataHandle;
- else
- if (AECoerceDesc(desc, typeChar, &tempDesc) == noErr)
- dataHandle = tempDesc.dataHandle;
- else
- return(errAECoercionFail);
-
- charCount = GetHandleSize(dataHandle);
- if (charCount > maxLength)
- {
- MyDisposeDescs(&tempDesc, kEndOfList);
- return(errAECoercionFail);
- }
-
- str[0] = charCount;
- HLock(dataHandle);
- BlockMove(*dataHandle, &str[1], charCount);
- HUnlock(dataHandle); // This may be from desc, so must unlock.
- MyDisposeDescs(&tempDesc, kEndOfList);
- return(noErr);
- }
-
- //----------------------------------------------------------------------------------//
- // Create the first window in response to the Open Application Apple Event. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleOpenApp(AppleEvent *theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (reply,refCon)
- WindowPtr window;
- OSErr err;
-
- if (!(err = GetMissingParams(theAppleEvent))) // Error if any parameters.
- {
- if (window = CreateNewWindow((WindowPtr)-1)) // Create initial window
- ShowWindow(window);
- else
- err = errAEEventNotHandled;
- }
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Send a Quit Application Apple Event to myself to terminate this app. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void SendQuitApp()
- {
- AppleEvent myAppleEvent, reply;
-
- // Create the Apple Event.
- FailIfErr(AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &gSelfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent));
- // Send the Apple Event.
- FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAENeverInteract, kAENormalPriority,
- kAEDefaultTimeout, nil, nil));
- AEDisposeDesc(&myAppleEvent); // Dispose of the Apple Event.
- }
-
- //----------------------------------------------------------------------------------//
- // Quit the application. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleQuitApp(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (reply,refCon)
- OSErr err;
-
- if (!(err = GetMissingParams(theAppleEvent))) // Error if there are any parameters.
- Terminate();
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // This routine makes a clone of the given window by copying its bounds, zoom //
- // state, and title (with the addition of "copy") properties. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- WindowPtr CloneWindow(WindowPtr windowToClone, WindowPtr behindWindow)
- {
- WindowPtr clonedWindow;
- Rect bounds;
- Str255 title;
-
- if (clonedWindow = CreateNewWindow(behindWindow))
- {
- GetWTitle(windowToClone, title);
- p2cstr(title);
- strcat((char *)title, " copy\0");
- c2pstr((char *)title);
- bounds = GetWindowBounds(windowToClone);
- SetWTitle(clonedWindow, title);
- MoveWindow(clonedWindow, bounds.left, bounds.top, false);
- SizeWindow(clonedWindow, bounds.right-bounds.left, bounds.bottom-bounds.top, true);
- SetWRefCon(clonedWindow, GetWRefCon(windowToClone));
- return(clonedWindow);
- }
- return(nil);
- }
-
- //----------------------------------------------------------------------------------//
- // Handle the Clone Apple Event and create a clone of the given object. To clone //
- // a window, I clone its bounds, zoom state, and visible properties. In addition, //
- // I clone the window's title and append " copy" to it for the cloned window's //
- // title. If the insertion location parameter is not in the event record, I //
- // perform the default behavior, which is to position the clone behind the //
- // window being cloned. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleClone(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (refCon)
- AEDesc cloneObject, windowObject, replyObject, insertionLoc;
- AERecord insertionRec;
- DescType theType, position;
- WindowPtr windowToClone, window, rplcWindow, behindWindow = nil;
- Size paramSize;
- OSErr err = noErr;
-
-
- MyInitDescs(&cloneObject,&windowObject,&replyObject,&insertionLoc,&insertionRec,kEndOfList);
- // Let's get the direct object, the object to clone.
- if (err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &cloneObject))
- goto myExit;
- if (!(windowToClone = ResolveToWindow(&cloneObject)))
- {
- err = errAENoSuchObject;
- goto myExit;
- }
- else // we have a window to clone.
- {
- if (!(err = AEGetParamDesc(theAppleEvent,keyAEInsertHere,typeInsertionLoc,&insertionLoc)))
- if (!(err = AECoerceDesc(&insertionLoc, typeAERecord, &insertionRec)))
- // Get object as typeWildCard because it may be null or an object specifier.
- if (!(err = AEGetKeyDesc(&insertionRec, keyAEObject, typeWildCard, &windowObject)))
- if (!(err = AEGetKeyPtr(&insertionRec,keyAEPosition,typeEnumeration,&theType,
- (Ptr)&position,sizeof(DescType),¶mSize)))
- err = FindRelativeWindow(&behindWindow, &windowObject, position, &rplcWindow);
-
- if (err)
- if (err == errAEDescNotFound)
- behindWindow = windowToClone; // Registry's default behavior.
- else
- goto myExit;
- }
-
- if (window = CloneWindow(windowToClone, behindWindow))
- {
- if (((WindowPeek)windowToClone)->visible)
- ShowWindow(window);
- if (position == kAEReplace)
- CloseTheWindow(rplcWindow);
-
- if (reply->dataHandle != nil)
- {
- CreateWindowObjectSpec(window, kIndexKeyForm, &replyObject);
- err = AEPutParamDesc(reply, keyAEResult, &replyObject);
- }
- }
- else
- err = errAEEventNotHandled;
-
- myExit:
- MyDisposeDescs(&cloneObject,&windowObject,&replyObject,&insertionLoc,&insertionRec,kEndOfList);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Send a Close Apple Event to myself to close the specified window. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void SendClose(WindowPtr window)
- {
- AppleEvent myAppleEvent, reply;
- AEDesc windowObject; // The window object specifier.
-
- // Create the Close Apple Event.
- FailIfErr(AECreateAppleEvent(kAECoreSuite, kAEClose, &gSelfAddress, kAutoGenerateReturnID,
- kAnyTransactionID, &myAppleEvent));
- // Create the window object specifier and add this to myAppleEvent.
- CreateWindowObjectSpec(window, kIndexKeyForm, &windowObject);
- FailIfErr(AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObject));
- // Send the Apple Event.
- FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract, kAENormalPriority,
- kAEDefaultTimeout, nil, nil));
- // Now dispose of the AppleEvent and object specifier.
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(&windowObject);
- }
-
- //----------------------------------------------------------------------------------//
- // Respond to the Close Apple Event by closing the specified window object. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleClose(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (reply,refCon)
- AEDesc windowObject;
- WindowPtr windowToClose;
- OSErr myErr;
-
- MyInitDescs(&windowObject,kEndOfList);
- // First, get the direct object which is the object to close.
- myErr = AEGetParamDesc(theAppleEvent,keyDirectObject,typeObjectSpecifier,&windowObject);
- if (!myErr && !(myErr = GetMissingParams(theAppleEvent)))
- {
- if (windowToClose = ResolveToWindow(&windowObject))
- CloseTheWindow(windowToClose);
- else
- myErr = errAENoSuchObject;
- }
- MyDisposeDescs(&windowObject,kEndOfList);
- return(myErr);
- }
-
- //----------------------------------------------------------------------------------//
- // Respond to the Count Elements Apple Event. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleCountElements(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (refCon)
- AEDesc directObject;
- DescType theType, theClass;
- Size paramSize;
- OSErr err;
-
-
- MyInitDescs(&directObject, kEndOfList);
- // Get the direct object, should be null.
- if (!(err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &directObject)))
- if (!(err = AEGetParamPtr(theAppleEvent,keyAEObjectClass,typeType,&theType,(Ptr)&theClass,
- sizeof(DescType),¶mSize))) // Get class of elements to count.
- err = GetMissingParams(theAppleEvent); // Error if more parameters.
-
- if (err)
- goto myExit;
-
- // If we had a deeper object hierarchy, we'd probably call AEResolve here, but...
- // we only handle the window class contained within the null object.
- if (theClass == cWindow && directObject.descriptorType == typeNull)
- err = AEPutParamPtr(reply, keyAEResult, typeLongInteger, (Ptr)&gNumWindowsOpen, sizeof(long));
-
- myExit:
- MyDisposeDescs(&directObject, kEndOfList);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Send a Create Element Apple Event to myself to create a new window. By default, //
- // I am setting the position to the beginning of the null container (frontmost). //
- // In this case, as well as at the end of the container, the object parameter is //
- // the null container. If the position is before, after, or replace, the object //
- // parameter must be an object specifier to indicate the relative window. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void SendCreateElement()
- {
- AppleEvent myAppleEvent, reply;
- AERecord insertionRec; // Insertion Loc record.
- AEDesc insertionLoc; // The coerced insertionRec.
- DescType theType;
-
- // Create the Apple Event.
- FailIfErr(AECreateAppleEvent(kAECoreSuite, kAECreateElement, &gSelfAddress, kAutoGenerateReturnID,
- kAnyTransactionID, &myAppleEvent));
- // Attach the class of the new element, which in this case is cWindow.
- theType = cWindow;
- FailIfErr(AEPutParamPtr(&myAppleEvent, keyAEObjectClass, typeType, (Ptr)&theType, sizeof(DescType)));
-
- // Create insertion loc, object is null container and position is beginning.
- FailIfErr(AECreateList(nil, 0, true, &insertionRec)); // Create an AE Record.
- theType = kAEBeginning;
- FailIfErr(AEPutKeyDesc(&insertionRec, keyAEObject, &gNullDesc));
- FailIfErr(AEPutKeyPtr(&insertionRec, keyAEPosition, typeEnumeration, (Ptr)&theType, sizeof(DescType)));
- FailIfErr(AECoerceDesc(&insertionRec, typeInsertionLoc, &insertionLoc));
- // Now add the insertion location descriptor record to the Apple Event.
- FailIfErr(AEPutParamDesc(&myAppleEvent, keyAEInsertHere, &insertionLoc));
- // Send the Apple Event.
- FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract, kAENormalPriority,
- kAEDefaultTimeout, nil, nil));
- // Now dispose of the AppleEvent and other records.
- MyDisposeDescs(&myAppleEvent, &insertionRec, &insertionLoc, kEndOfList);
- }
-
- //----------------------------------------------------------------------------------//
- // Respond to the Create Element Apple event and create a new window. For this //
- // application, the keyAEInsertHere parameter is optional. If this parameter is //
- // not present, a new window is created in the frontmost position. //
- // This routine also handles the optional initial data parameters (keyAEData and //
- // keyAEPropData) if they are present. A window object specifier must be in the //
- // keyAEData parameter, which is essentially used to make a clone. If the //
- // property data exists, these properties will override those previously set. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleCreateElement(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (refCon)
- AEDesc windowObject, dataObject, propData, propObject, replyObject;
- AEDesc insLocParam;
- AERecord insLocRec;
- AERecord dataPropParam; // Initial data parameters.
- AEKeyword keyWord; // Property id code for PropData.
- DescType theType, theClass, position;
- WindowPtr window, relativeWindow, dataWindow, rplcWindow;
- Rect bounds;
- Size theSize;
- Str255 buffer;
- long numItems;
- short i;
- Boolean isVisible;
- OSErr err;
-
- if (err = AEGetParamPtr(theAppleEvent, keyAEObjectClass, typeType, &theType, (Ptr)&theClass,
- sizeof(DescType), &theSize))
- return(err);
- if (theClass != cWindow) // We only handle elements of the class cWindow.
- return(errAEEventNotHandled);
- position = typeNull;
- MyInitDescs(&windowObject,&dataObject,&propData,&propObject,&insLocParam,&dataPropParam,&replyObject,&insLocRec,kEndOfList);
- // Now get the insertion location record as an AERecord, if it exists.
- if (!(err = AEGetParamDesc(theAppleEvent, keyAEInsertHere, typeInsertionLoc, &insLocParam)))
- { // coerce the insertion loc record to an AE record.
- err = AECoerceDesc(&insLocParam, typeAERecord, &insLocRec);
- // Get the object as typeWildCard because it may be a null descriptor or an object.
- if (!(err = AEGetKeyDesc(&insLocRec, keyAEObject, typeWildCard, &windowObject)))
- if (!(err = AEGetKeyPtr(&insLocRec, keyAEPosition, typeEnumeration, &theType, (Ptr)&position,
- sizeof(DescType), &theSize)))
- {
- relativeWindow = nil;
- err = FindRelativeWindow(&relativeWindow, &windowObject, position, &rplcWindow);
- }
- }
- else
- if (err == errAEDescNotFound) // No insertion loc, make it frontmost by default.
- {
- relativeWindow = (WindowPtr)-1;
- position = kAEBeginning;
- err = noErr; // Not an error for me because I make this param optional.
- }
-
- if (err)
- goto myExit;
-
- // Check if optional data parameter is present.
- if (!(err = AEGetParamDesc(theAppleEvent,keyAEData,typeObjectSpecifier,&dataObject)))
- {
- if (dataWindow = ResolveToWindow(&dataObject))
- {
- window = CloneWindow(dataWindow, relativeWindow);
- isVisible = ((WindowPeek)dataWindow)->visible;
- }
- else
- {
- err = errAENoSuchObject;
- goto myExit;
- }
- }
- else
- if (err == errAEDescNotFound) // The optional data parameter is not present.
- {
- if (window = CreateNewWindow(relativeWindow))
- {
- err = noErr;
- isVisible = true;
- if (position == kAEReplace) // Replace the window in the right position.
- {
- bounds = GetWindowBounds(rplcWindow);
- MoveWindow(window, bounds.left, bounds.top, false);
- }
- }
- else
- {
- err = errAEEventNotHandled; // couldn't create a new window.
- goto myExit;
- }
- }
- else
- goto myExit;
-
- if (isVisible) // We set the visibility here because it may be changed
- ShowWindow(window); // by the following property data.
-
- // Handle PropData parameter if it exists.
- if (!(err = AEGetParamDesc(theAppleEvent,keyAEPropData,typeAERecord,&dataPropParam)))
- {
- AECountItems(&dataPropParam, &numItems);
- for (i = 1; i <= numItems; i++)
- {
- if (!(err = AEGetNthPtr(&dataPropParam,i,typeWildCard,&keyWord,&theType,&buffer,sizeof(Str255),&theSize)))
- {
- AECreateDesc(keyWord, (Ptr)&window, sizeof(Ptr), &propObject);
- AECreateDesc(theType, (Ptr)&buffer, theSize, &propData);
- err = DoSetData(&propObject, &propData);
- AEDisposeDesc(&propObject);
- AEDisposeDesc(&propData);
- if (err)
- break;
- }
- }
- }
-
- if (!err || err == errAEDescNotFound)
- {
- if (position == kAEReplace)
- CloseTheWindow(rplcWindow);
- err = noErr;
- if (reply->dataHandle != nil)
- {
- CreateWindowObjectSpec(window, kIndexKeyForm, &replyObject);
- err = AEPutParamDesc(reply, keyAEResult, &replyObject);
- }
- }
-
- myExit:
- MyDisposeDescs(&windowObject,&dataObject,&propData,&propObject,&insLocParam,&dataPropParam,&replyObject,&insLocRec,kEndOfList);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Respond to the Do Objects Exist AE by attempting to resolve the object specifier//
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleDoObjectsExist(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (reply,refCon)
- AEDesc target, token;
- Boolean exists;
- OSErr err;
-
- MyInitDescs(&target, &token, kEndOfList);
- if (!(err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &target)))
- if (!(err = GetMissingParams(theAppleEvent))) // Check for missing params.
- {
- exists = true;
- token.descriptorType = typeNull;
- if (target.descriptorType != typeNull)
- exists = (AEResolve(&target, kAEIDoMinimum, &token) == noErr);
-
- // Add data to the reply Apple event record.
- err = AEPutParamPtr(reply, keyDirectObject,typeBoolean,(Ptr)&exists,sizeof(Boolean));
- }
- myExit:
- MyDisposeDescs(&target, &token, kEndOfList);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Send the Set Data Apple Event with the object, property, and property data. //
- // *NOTE*: I am sending myself the Set Data event in response to user interaction. //
- // These actions have already occurred by this time, so I am sending the event //
- // with the "don't execute" flag set for "smart" recorders. A "smart" recorder //
- // would check this flag when it intercepts the Apple event, and if it was set, //
- // it wouldn't pass the event to the application. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void SendSetData( AEDesc* propDesc, // the property to set
- AEDesc* propData, // the property data
- AEDesc* target ) // object to set property of
- {
- AppleEvent myAppleEvent, reply;
- AEDesc objectToSet;
-
- FailIfErr(AECreateAppleEvent(kAECoreSuite, kAESetData, &gSelfAddress, kAutoGenerateReturnID,
- kAnyTransactionID, &myAppleEvent));
- // Create the object specifier for the property of the object.
- FailIfErr(CreateObjSpecifier(cProperty, target, formPropertyID, propDesc,
- false, &objectToSet));
- // Attach the property object specifier.
- FailIfErr(AEPutParamDesc(&myAppleEvent, keyDirectObject, &objectToSet));
- // Add the property data.
- FailIfErr(AEPutParamDesc(&myAppleEvent, keyAEData, propData));
- FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract+kAEDontExecute, kAENormalPriority,
- kAEDefaultTimeout, nil, nil));
-
- AEDisposeDesc(&objectToSet); // Clean up.
- AEDisposeDesc(&myAppleEvent);
- }
-
- //----------------------------------------------------------------------------------//
- // To set the data of an object, the expected data is passed in its raw form with //
- // the property type in the descriptorType field and the data in the dataHandle. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleSetData(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (reply,refCon)
- AEDesc target, data, token;
- OSErr err;
-
- MyInitDescs(&target, &data,&token, kEndOfList);
- // First, get the direct object. This is the object whose data is to be set.
- if (!(err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &target)))
- if (!(err = AEResolve(&target, kAEIDoMinimum, &token))) // Resolve it.
- if (!(err = AEGetParamDesc(theAppleEvent, keyAEData, typeWildCard, &data)))
- err = DoSetData(&token, &data);
- MyDisposeDescs(&target, &data, &token, kEndOfList);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Return a reply to the Get Data or Get Data Size Apple Event for the requested //
- // data. The refcon parameter is used to distinguish the two events. If typeBest //
- // is the requested return type, the data's descriptor type is the result type. //
- // **NOTE: Do not use the same descriptor as source and dest in AECoerceDesc(). //
- // This routine creates a copy of the source, and then it is impossible to dispose //
- // of the memory originally contained in the source's dataHandle. //
- // 2/25/92 - Removed FailIfErr calls. Now the error is returned as a result. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleGetData( AppleEvent* theAppleEvent,
- AppleEvent* reply,
- long refCon ) // kAEGetData or kAEGetDataSize.
- {
- AEDesc theObject, token; // direct object and resolved token.
- AEDesc objectData, tempDesc; // object data, and coerced data.
- DescType reqType;
- WindowPtr window;
- Size theSize;
- OSErr err;
-
- MyInitDescs(&theObject, &objectData, &token, kEndOfList);
- // First, get the direct objet.
- if (err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &theObject))
- goto myExit;
- // Next, get the requested return type, if it exists.
- if (err = AEGetParamPtr(theAppleEvent, keyAERequestedType, typeType, &reqType,
- (Ptr)&reqType, sizeof(DescType), &theSize))
- {
- if (err == errAEDescNotFound) // not an error if return type is not found
- {
- err = noErr;
- reqType = typeWildCard;
- }
- else
- goto myExit;
- }
- if (err = GetMissingParams(theAppleEvent)) // check for missing params
- goto myExit;
-
- // Resolve the object specifier and get the token containing the property and container.
- if (!(err = AEResolve(&theObject, kAEIDoMinimum, &token)))
- if (window = (WindowPtr)*(LongPtr)*token.dataHandle) // Nil for application; WindowPtr for window
- err = GetWindowData(token.descriptorType, window, &objectData);
- else
- err = GetAppData(token.descriptorType, &objectData);
-
- if (err == noErr && reply->dataHandle != nil)
- { // Add data to the reply Apple event record.
- if (reqType != typeWildCard && reqType != typeBest &&
- reqType != objectData.descriptorType)
- {
- err = AECoerceDesc(&objectData, reqType, &tempDesc);
- MyDisposeDescs(&objectData, kEndOfList);
- objectData.descriptorType = tempDesc.descriptorType;
- objectData.dataHandle = tempDesc.dataHandle;
- }
- if (!err)
- {
- if (refCon == kAEGetData) // return data
- err = AEPutParamDesc(reply, keyAEResult, &objectData);
- else if (refCon == kAEGetDataSize) // return data size
- {
- theSize = GetHandleSize(objectData.dataHandle);
- err = AEPutParamPtr(reply, keyAEResult, typeLongInteger, (Ptr)&theSize, sizeof(long));
- }
- }
- }
-
- myExit:
- MyDisposeDescs(&theObject, &objectData, &token, kEndOfList);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Send a Move Apple event to myself in response to a user selecting a window //
- // and making it frontmost. This event is sent with the insertion location record //
- // specifying the beginning of the null container. If the index is non-zero, this //
- // indicates that the move event has already been performed by DragWindow(). Thus, //
- // this event is passed with the don't execute flag set. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void SendMoveEvent(WindowPtr windowToMove, long index)
- {
- AppleEvent myAppleEvent, reply, windowObject;
- AERecord insertionRec; // Insertion Loc record.
- AEDesc insertionLoc; // The coerced insertionRec.
- DescType theType;
-
- // Create the Apple Event.
- FailIfErr(AECreateAppleEvent(kAECoreSuite, kAEMove, &gSelfAddress, kAutoGenerateReturnID,
- kAnyTransactionID, &myAppleEvent));
- // Create the object spec for the window to move.
- FailIfErr(CreateWindowObjectSpec(windowToMove, kIndexKeyForm, &windowObject));
- FailIfErr(AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObject));
-
- // Create insertion loc record for beginning of null container.
- FailIfErr(AECreateList(nil, 0, true, &insertionRec)); // Create an AE Record.
- theType = kAEBeginning;
- FailIfErr(AEPutKeyDesc(&insertionRec, keyAEObject, &gNullDesc));
- FailIfErr(AEPutKeyPtr(&insertionRec,keyAEPosition,typeEnumeration,(Ptr)&theType,sizeof(DescType)));
- FailIfErr(AECoerceDesc(&insertionRec, typeInsertionLoc, &insertionLoc));
- // Now add the insertion location descriptor record to the Apple Event.
- FailIfErr(AEPutParamDesc(&myAppleEvent, keyAEInsertHere, &insertionLoc));
- // Send the Apple Event.
- if (index)
- FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract+kAEDontExecute,
- kAENormalPriority, kAEDefaultTimeout, nil, nil));
- else
- FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract,
- kAENormalPriority, kAEDefaultTimeout, nil, nil));
-
- // Now dispose of the AppleEvent and other records.
- MyDisposeDescs(&myAppleEvent,&windowObject,&insertionRec,&insertionLoc,kEndOfList);
- }
-
- //----------------------------------------------------------------------------------//
- // Respond to the Move Apple Event by reordering the window list. For CoreSample, //
- // the keyAEInsertHere parameter is optional. If this parameter does not exist, //
- // the specified window will move the to the front. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr HandleMove(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
- {
- #pragma unused (refCon)
- AEDesc object, windowObj, replyObj, insertionLoc;
- AERecord insertionRec;
- DescType theType, position;
- WindowPtr windowToMove, relativeWindow, rplcWindow;
- Rect bounds;
- Size paramSize;
- OSErr err;
-
- MyInitDescs(&object,&windowObj,&insertionLoc,&insertionRec,&replyObj,kEndOfList);
- // First, get the direct parameter, the object to move.
- if (err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &object))
- goto myExit;
- if (!(windowToMove = ResolveToWindow(&object))) // Check if valid window object.
- {
- err = errAENoSuchObject;
- goto myExit;
- }
-
- // Retrieve the insertion location record, if it exists.
- if ((err = AEGetParamDesc(theAppleEvent,keyAEInsertHere,typeInsertionLoc,&insertionLoc)) == errAEDescNotFound)
- { // Execute *MY* default behavior since insertion loc param not present.
- SelectWindow(windowToMove);
- err = noErr;
- goto myExit;
- }
- else
- if (err)
- goto myExit;
- else // get data from insertion loc and coerce it to typeAERecord.
- {
- if ((err = GetMissingParams(theAppleEvent)) ||
- (err = AECoerceDesc(&insertionLoc, typeAERecord, &insertionRec)) ||
- (err = AEGetKeyDesc(&insertionRec,keyAEObject,typeWildCard,&windowObj)) ||
- (err = AEGetKeyPtr(&insertionRec,keyAEPosition,typeEnumeration,&theType,
- (Ptr)&position,sizeof(DescType),¶mSize)))
- goto myExit;
- }
-
- if (!(err = FindRelativeWindow(&relativeWindow,&windowObj,position,&rplcWindow)))
- {
- if (position == kAEReplace)
- if (windowToMove == rplcWindow)
- goto myExit; // do nothing.
- else
- {
- bounds = GetWindowBounds(rplcWindow);
- CloseTheWindow(rplcWindow);
- MoveWindow(windowToMove, bounds.left, bounds.top, false);
- }
-
- if (relativeWindow == (WindowPtr)-1) // [pwpc]
- SelectWindow(windowToMove);
- else
- if (windowToMove != relativeWindow)
- SendBehind(windowToMove, relativeWindow); // NOTE: may have to call PaintOne and
- // CalcVis if after; see IM I-286
- if (position == kAEReplace && windowToMove != rplcWindow)
- {
- bounds = GetWindowBounds(rplcWindow);
- CloseTheWindow(rplcWindow);
- MoveWindow(windowToMove, bounds.left, bounds.top, false);
- }
- }
-
- myExit:
- if (!err)
- if (reply->dataHandle != nil)
- {
- CreateWindowObjectSpec(windowToMove, kIndexKeyForm, &replyObj);
- err = AEPutParamDesc(reply, keyAEResult, &replyObj);
- }
- MyDisposeDescs(&object,&windowObj,&insertionLoc,&insertionRec,&replyObj,kEndOfList);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Set up the descriptor records needed to set the data for the bounds, position, //
- // and zoomed properties. The bounds is set in response to sizing a window; the //
- // position is set after dragging a window; and the isZoomed property is set when //
- // zooming a window in or out. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void SetUpPropertyData( WindowPtr window, // Window object.
- DescType propType, // Property descriptor type.
- DescType dataType, // Descriptor type for data.
- Size dataSize ) // Size of data.
- {
- AEDesc windowObject, theData, theProperty;
- Rect bounds;
- Boolean isZoomed;
-
- MyInitDescs(&windowObject, &theData, &theProperty, kEndOfList);
- if (propType == pIsZoomed)
- {
- isZoomed = (Boolean)GetWRefCon(window);
- FailIfErr(AECreateDesc(dataType,(Ptr)&isZoomed,dataSize,&theData));
- }
- else // it's either pBounds or pPosition.
- {
- bounds = GetWindowBounds(window);
- FailIfErr(AECreateDesc(dataType, (Ptr)&bounds, dataSize, &theData));
- }
-
- CreateWindowObjectSpec(window, kIndexKeyForm, &windowObject);
- FailIfErr(AECreateDesc(typeType, (Ptr)&propType, sizeof(DescType), &theProperty));
-
- SendSetData(&theProperty, &theData, &windowObject);
- MyDisposeDescs(&windowObject, &theData, &theProperty, kEndOfList);
- }
-
- //----------------------------------------------------------------------------------//
- // Set the property data for the specified object. For now, we only handle window //
- // objects, and you may only set the modifiable properties (defined in Registry). //
- // *NOTE*: We do not allow the application's properties to be modified. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- OSErr DoSetData( AEDesc* token, // Contains the property and object.
- AEDesc* data ) // Contains the data to set.
- {
- AEDesc propData; // Property data.
- Rect bounds;
- GrafPtr oldPort;
- WindowPtr window, behindWindow;
- Str255 name;
- long newIndex;
- short part;
- Boolean value;
- Point pt;
- OSErr err;
-
- err = noErr;
- if (window = (WindowPtr)*(LongPtr)*(token->dataHandle))
- {
- GetPort(&oldPort);
- switch (token->descriptorType)
- {
- case pBounds:
- if (data->descriptorType != typeQDRectangle)
- {
- propData.dataHandle = nil;
- err = AECoerceDesc(data, typeQDRectangle, &propData);
- bounds = *(Rect *)*propData.dataHandle; // Get content region.
- MyDisposeDescs(&propData, kEndOfList);
- }
- else
- bounds = *(Rect *)*data->dataHandle; // Get content region.
-
- if (!err)
- {
- SetPort(window);
- InvalRect(&window->portRect);
-
- // Real applications may want to make a sanity check on the new bounds.
- MoveWindow(window, bounds.left, bounds.top, false);
- SizeWindow(window, bounds.right-bounds.left, bounds.bottom-bounds.top, true);
- InvalRect(&window->portRect);
- }
- break;
-
- case pIndex:
- if (DescToLong(data,&newIndex) != noErr)
- return(errAECoercionFail); // Data cannot be coerced.
-
- if (newIndex > gNumWindowsOpen)
- err = errAEIndexTooLarge;
- else
- {
- if (newIndex == 1)
- SelectWindow(window);
- else
- if (behindWindow = GetWindowAtIndex(newIndex))
- SendBehind(window, behindWindow);
- else
- err = errAEEventFailed;
- }
- break;
-
- case pIsZoomed:
- if (DescToBoolean(data,&value) != noErr)
- return(errAECoercionFail); // Data cannot be coerced.
-
- part = value ? inZoomOut : inZoomIn;
- ZoomIt(window, part);
- break;
-
- case pName:
- if (DescToPString(data,name,kMaxStrSize) != noErr)
- return(errAECoercionFail);
- SetWTitle(window, name);
- break;
-
- case pPosition:
- if (data->descriptorType != typeQDPoint)
- {
- propData.dataHandle = nil;
- err = AECoerceDesc(data, typeQDPoint, &propData);
- pt = *(Point *)*propData.dataHandle;
- MyDisposeDescs(&propData, kEndOfList);
- }
- else
- pt = *(Point *)*data->dataHandle;
-
- if (!err)
- {
- // Real applications may want to make a sanity check on the new loc.
- SetPort(window);
- MoveWindow(window, pt.h, pt.v, false);
- InvalRect(&window->portRect);
- }
- break;
-
- case pVisible:
- if (DescToBoolean(data,&value) != noErr)
- return(errAECoercionFail); // Data cannot be coerced.
- if (value)
- ShowWindow(window);
- else
- HideWindow(window);
- break;
-
- default: // No other properties are modifiable.
- return(errAENotModifiable);
- }
- SetPort(oldPort);
- }
- else
- return(errAEEventFailed);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // This is a dummy handler that receives Apple events which I don't handle. It //
- // is mainly provided as a stub in order to support all the events in the //
- // required suite, as well as the entire core suite. This is the handler for the //
- // Open Document and Print Document events (required suite); and the Save, Get //
- // Class Info, and Get Event Info events (core suite). The Get Class Info and Get //
- // Event Info events "MAY" be supported internally in the future, so applications //
- // will not need to handle these events themselves. This support may be provided //
- // since it would be consistent across all applications, and the information may //
- // be retrieved from the 'aeut'/'aete' resources. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr DummyHandler( AppleEvent *theAppleEvent,
- AppleEvent *reply,
- long refCon )
- {
- #pragma unused (theAppleEvent,reply,refCon)
- return(errAEEventNotHandled);
- }
-
- //----------------------------------------------------------------------------------//
- // Locate the window that is relative to the specified window object at the //
- // insertion position. If the location is replace, the window to replace is //
- // closed, and its bounds are returned to the calling routine. //
- // **Note**: if windowObj is used within this routine, the object param will //
- // contain the same dataHandle. This will be disposed of by the calling routine. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- OSErr FindRelativeWindow( WindowPtr* relativeWindow, // window before insertion loc.
- AEDesc* object, // object to be relative to.
- DescType position, // insertion position.
- WindowPtr* replaceWindow ) // window to replace.
- {
- AEDesc windowObj; // Coerced descriptor.
- WindowPtr windowToReplace;
- long index;
- OSErr err;
-
- err = noErr;
- *replaceWindow = nil;
- switch(position)
- {
- case kAEBeginning: // The object should be the container.
- if (object->descriptorType == typeNull)
- *relativeWindow = (WindowPtr)-1;
- else
- err = errAENoSuchObject;
- break;
-
- case kAEEnd: // The object should be the container.
- if (object->descriptorType == typeNull)
- *relativeWindow = nil;
- else
- err = errAENoSuchObject;
- break;
-
- case kAEBefore: // The object should be an object specifier.
- case kAEReplace:
- if (object->descriptorType != typeObjectSpecifier)
- {
- err = AECoerceDesc(object, typeObjectSpecifier, &windowObj);
- MyDisposeDescs(object, kEndOfList);
- object->descriptorType = windowObj.descriptorType;
- object->dataHandle = windowObj.dataHandle;
- }
-
- if (!err)
- if (windowToReplace = ResolveToWindow(object))
- {
- index = GetWindowIndexNum(windowToReplace);
- *relativeWindow = (index==1) ? (WindowPtr)-1 : GetWindowAtIndex(index-1);
- if (position == kAEReplace)
- *replaceWindow = windowToReplace;
- }
- else // We weren't able to resolve the object specifier to a window.
- err = errAENoSuchObject;
- break;
-
- case kAEAfter: // The object should be an object specifier.
- if (object->descriptorType != typeObjectSpecifier)
- {
- err = AECoerceDesc(object,typeObjectSpecifier,&windowObj);
- MyDisposeDescs(object, kEndOfList);
- object->descriptorType = windowObj.descriptorType;
- object->dataHandle = windowObj.dataHandle;
- }
-
- if (!err)
- if (!(*relativeWindow = ResolveToWindow(object)))
- err = errAENoSuchObject;
- break;
-
- default:
- return(errAEEventNotHandled);
- }
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Retrieves the data for the specified property of the window. The result token //
- // contains the type of the data in the descriptorType field, and the data itself //
- // in the dataHandle field. I know my application's window properties //
- // (i.e., has title bar, has close box, is zoomable, etc.), so I set up the //
- // result token accordingly. If your application handles various window types, //
- // you may need to look at the window defproc to determine which type of window it //
- // is. If the property is pBestType or pDefaultType, I return an object specifier//
- // for the window which may be used to easily reference it. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- OSErr GetWindowData( DescType theProperty, // Window property.
- WindowPtr window,
- AEDesc *result ) // Contains the result upon return.
- {
- DescType theType;
- Str255 title;
- Rect bounds;
- long index;
- Boolean myAnswer;
-
- switch (theProperty)
- {
- case pBestType:
- case pDefaultType:
- return(CreateWindowObjectSpec(window, kIndexKeyForm, result));
-
- case pBounds:
- bounds = GetWindowBounds(window);
- return(AECreateDesc(typeQDRectangle, (Ptr)&bounds, sizeof(Rect), result));
-
- case pClass:
- theType = cWindow;
- return(AECreateDesc(typeType, (Ptr)&theType, sizeof(DescType), result));
-
- case pIndex:
- index = GetWindowIndexNum(window);
- return(AECreateDesc(typeLongInteger, (Ptr)&index, sizeof(long), result));
-
- case pName:
- GetWTitle(window, title);
- return(AECreateDesc(typeChar, (Ptr)&title[1], title[0], result));
-
- case pPosition:
- bounds = GetWindowBounds(window);
- return(AECreateDesc(typeQDPoint, (Ptr)&bounds, sizeof(Point), result));
-
- case pHasCloseBox:
- case pHasTitleBar:
- case pIsResizable:
- case pIsZoomable:
- myAnswer = true;
- return(AECreateDesc(typeBoolean, (Ptr)&myAnswer, sizeof(Boolean), result));
-
- case pIsFloating:
- case pIsModal:
- myAnswer = false;
- return(AECreateDesc(typeBoolean, (Ptr)&myAnswer, sizeof(Boolean), result));
-
- case pIsZoomed:
- myAnswer = GetWRefCon(window);
- return(AECreateDesc(typeBoolean, (Ptr)&myAnswer, sizeof(Boolean), result));
-
- case pVisible: // Must check this because it is modifiable.
- myAnswer = ((WindowPeek)window)->visible;
- return(AECreateDesc(typeBoolean, (Ptr)&myAnswer, sizeof(Boolean), result));
-
- case pSelection: // No selection in CoreSample.
- return(errAENoSuchObject);
-
- default: // We don't handle requested property.
- return(errAEEventNotHandled);
- }
- }
-
- //----------------------------------------------------------------------------------//
- // Get the property data for the application and return it in the result parameter.//
- // The result token contains the property type in the descriptorType field, and //
- // a nil value in the dataHandle field to represent the null application. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- OSErr GetAppData( DescType theProperty,
- AEDesc* result ) // Descriptor record to hold the property data.
- {
- ProcessInfoRec myProcessInfo; // [pwpc]
- DescType theType;
- short refNum;
- Str255 name;
- Handle myHandle;
- ProcessSerialNumber thePSN, currentProcess;
- Boolean isFront;
- OSErr err;
-
- switch (theProperty)
- {
- case pBestType: // Return the null descriptor representing
- case pDefaultType: // the application.
- return(AEDuplicateDesc(&gNullDesc, result));
-
- case pClass:
- theType = cApplication;
- return(AECreateDesc(typeType,(Ptr)&theType,sizeof(DescType),result));
-
- case pName:
- // [pwpc] Clear out the name, and then call the process manager to get
- // the string for the name of our application.
-
- name[0] = 0;
- myProcessInfo.processInfoLength = sizeof(myProcessInfo);
- myProcessInfo.processName = name;
- myProcessInfo.processAppSpec = NULL;
-
- GetCurrentProcess(¤tProcess);
- GetProcessInformation(¤tProcess, &myProcessInfo);
-
- // Create an AEDesc returning the application name string
- // returned by the process manager.
-
- return(AECreateDesc(typeChar, (Ptr)&name[1], name[0], result));
-
- case pIsFrontProcess:
- GetFrontProcess(&thePSN);
- SameProcess(&gSelfPSN, &thePSN, &isFront);
- return(AECreateDesc(typeBoolean,(Ptr)&isFront,sizeof(Boolean),result));
-
- case pVersion:
- refNum = CurResFile(); // save current resource
- UseResFile(gRefNum); // set this resource to be current
- myHandle = (Handle)Get1Resource((ResType)'vers', 1);
- HLock(myHandle);
- err = AECreateDesc(typeVersion, *myHandle, GetHandleSize(myHandle), result);
- HUnlock(myHandle);
- UseResFile(refNum); // reset back to resource previously set
- return(err);
-
- default: // We don't handle the requested property.
- return(errAEEventNotHandled);
- }
- }
-
- //----------------------------------------------------------------------------------//
- // Create an object specifier for the window with the indicated key form. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- OSErr CreateWindowObjectSpec( WindowPtr window,
- short keyForm, // index or name key form.
- AEDesc* objectSpec ) // Resulting object specifier.
- {
- AEDesc data;
- Str255 title;
- long index;
- OSErr err;
-
- MyInitDescs(&data, kEndOfList);
- switch(keyForm)
- {
- case kNameKeyForm: // Object specifier with name.
- GetWTitle(window, title);
- if (!(err = AECreateDesc(typeChar, (Ptr)&title[1], title[0], &data)))
- err = CreateObjSpecifier(cWindow, &gNullDesc, formName, &data,
- false, objectSpec);
- break;
-
- case kIndexKeyForm: // Object specifier with index.
- index = GetWindowIndexNum(window);
- if (!(err = CreateOffsetDescriptor(index, &data)))
- err = CreateObjSpecifier(cWindow, &gNullDesc, formAbsolutePosition, &data,
- false, objectSpec);
- break;
- }
- MyDisposeDescs(&data, kEndOfList);
- return(err);
- }
-
- //----------------------------------------------------------------------------------//
- // Check to see if there exists any additional parameters in the Apple Event. //
- // If so, return an error to the calling routine. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- OSErr GetMissingParams(AppleEvent* theAppleEvent)
- {
- DescType theType;
- Size actualSize;
- OSErr err;
-
- err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
- &theType, nil, 0, &actualSize);
- if (err == errAEDescNotFound)
- return(noErr);
- else
- return(errAEEventNotHandled);
- }
-
- //----------------------------------------------------------------------------------//
- // If a reply is expected, the error number is returned in the reply parameter. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- void ReportError( AppleEvent* reply,
- long err )
- {
- if (reply->dataHandle != nil && err != noErr)
- FailIfErr(AEPutParamPtr(reply,keyErrorNumber,typeLongInteger,(Ptr)&err,sizeof(long)));
- }
-
- //----------------------------------------------------------------------------------//
- // This routine returns the window object contained in the given object specifier. //
- // If the resolution does not return a descriptor record of type cWindow, nil is //
- // returned as a result. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- WindowPtr ResolveToWindow(AEDesc* objectSpecifier)
- {
- AEDesc token;
- WindowPtr window;
-
-
- MyInitDescs(&token, kEndOfList);
- window = nil;
- if (objectSpecifier->descriptorType == typeObjectSpecifier)
- if (!(AEResolve(objectSpecifier, kAEIDoMinimum, &token)))
- if (token.descriptorType == cWindow)
- window = (WindowPtr)*((LongPtr)*(token.dataHandle));
-
- MyDisposeDescs(&token, kEndOfList);
- return(window);
- }
-
- //----------------------------------------------------------------------------------//
- // Retrieve the window from the null container by the key form and return its //
- // pointer in the dataHandle field of resultToken. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr WindowAccessor( DescType classWanted, // window class
- AEDesc* container, // the application (null container)
- DescType containerClass,
- DescType keyform,
- AEDesc* selectionData,
- AEDesc* resultToken, // specified window is returned in result
- long theRefCon )
- {
- #pragma unused (classWanted,container,containerClass,theRefCon)
- WindowPtr window;
- DescType seldataType;
- Str255 title;
- long index;
- OSErr err;
-
- window = nil;
- err = noErr;
- if (!gNumWindowsOpen)
- return(errAENoSuchObject);
- else
- {
- seldataType = selectionData->descriptorType;
-
- switch(keyform)
- {
- case formName: // Window title.
- if (DescToPString(selectionData,title,kMaxStrSize) != noErr)
- return(errAECoercionFail);
- if (!(window = GetWindowWithTitle(title)))
- return(errAENoSuchObject); // Window was not found.
- break;
-
- case formAbsolutePosition:
- if (DescToLong(selectionData,&index) != noErr)
- return(errAECoercionFail); // Data cannot be coerced.
- if (!(window = GetWindowAtIndex(index)))
- return(errAENoSuchObject); // Window was not found.
- break;
-
- default: // I don't handle any other key forms.
- return(errAEEventNotHandled);
- }
- }
- return(AECreateDesc(cWindow, (Ptr)&window, sizeof(Ptr), resultToken));
- }
-
- //----------------------------------------------------------------------------------//
- // Return a token representing the property for the containing window. The token //
- // is returned with the property and window pointer. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr WindowPropertyAccessor( DescType classWanted, // Property class
- AEDesc* container, // Window object
- DescType containerClass,
- DescType form,
- AEDesc* selectionData,
- AEDesc* resultToken,
- long theRefCon )
- {
- #pragma unused (containerClass, theRefCon)
- Ptr window;
- DescType propType;
-
- // Let's make sure we're accessing a valid descriptor type.
- if ((classWanted != cProperty) || (form != formPropertyID))
- return(errAEWrongDataType);
-
- window = (Ptr)*(LongPtr)*(container->dataHandle); // Get the window pointer.
- propType = *(LongPtr)*selectionData->dataHandle; // Get the property type.
- return(AECreateDesc(propType, (Ptr)&window, sizeof(Ptr), resultToken));
- }
-
- //----------------------------------------------------------------------------------//
- // Return a token that contains the property type and nil to represent the null //
- // container (the application). //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- pascal
- OSErr AppPropertyAccessor( DescType classWanted, // Property class.
- AEDesc* container, // Application.
- DescType containerClass,
- DescType form,
- AEDesc* selectionData,
- AEDesc* resultToken,
- long theRefCon )
- {
- #pragma unused (container,containerClass,theRefCon)
- DescType propType;
- long nilValue;
-
- // Let's make sure we're accessing a valid descriptor type.
- if ((classWanted != cProperty) || (form != formPropertyID))
- return(errAEWrongDataType);
- nilValue = nil;
- propType = *(LongPtr)*selectionData->dataHandle; // Get the property type.
- return(AECreateDesc(propType, (Ptr)&nilValue, sizeof(long), resultToken));
- }
-
- //----------------------------------------------------------------------------------//
- // Returns the window with the given title if found. Otherwise, nil is returned. //
- // Use WindowList in order to find windows that may be invisible. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- WindowPtr GetWindowWithTitle( ConstStr255Param titleToFind )
- {
- WindowPeek window;
- Str255 thisTitle;
-
- #ifdef THINK_C
- window = (WindowPeek)WindowList; // WindowList finds invisible windows as well.
- #else
- window = *(PeekPtr)WindowList; // WindowList finds invisible windows as well.
- #endif
-
- while (window)
- {
- GetWTitle((WindowPtr)window, thisTitle);
- if (EqualString(thisTitle, titleToFind, false, false))
- return((WindowPtr)window);
- window = window->nextWindow;
- }
- return(nil);
- }
-
- //----------------------------------------------------------------------------------//
- // Search all windows (including invisible), and return the window at the given //
- // index if found. Otherwise, nil is returned. This routine also handles negative //
- // indices which indicates that the offset is from the end of the container. // //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- WindowPtr GetWindowAtIndex(long index)
- {
- WindowPeek window;
- short count;
-
- index = index < 0 ? gNumWindowsOpen+index+1 : index;
- count = 1;
-
- #ifdef THINK_C
- window = (WindowPeek)WindowList; // WindowList finds invisible windows as well.
- #else
- window = *(PeekPtr)WindowList; // WindowList finds invisible windows as well.
- #endif
-
- while (window)
- {
- if (count == index)
- return((WindowPtr)window);
- window = window->nextWindow;
- count++;
- }
- return(nil);
- }
-
- //----------------------------------------------------------------------------------//
- // Returns the index number of the given window, where 1 is the frontmost. //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- long GetWindowIndexNum(WindowPtr myWindow)
- {
- WindowPeek thisWindow;
- long index;
-
- #ifdef THINK_C
- thisWindow = (WindowPeek)WindowList; // Compilers are so much fun!!.
- #else
- thisWindow = *(PeekPtr)WindowList; // WindowList finds invisible windows as well.
- #endif
-
- index = 1;
-
- while (thisWindow)
- {
- if (thisWindow == (WindowPeek)myWindow) // [pwpc]
- return(index);
- thisWindow = thisWindow->nextWindow;
- index++;
- }
- return(nil);
- }
-
- //----------------------------------------------------------------------------------//
- // This routine returns the bounds of a given window. Special calculations are //
- // performed when the bounds is invalid (i.e., the window is hidden). //
- //----------------------------------------------------------------------------------//
- #pragma segment Main
- Rect GetWindowBounds(WindowPtr window)
- {
- Rect portRect, bitMapRect, bounds;
-
- bounds = (*((WindowPeek)window)->contRgn)->rgnBBox; // check the content region.
- if (bounds.top == 0 && bounds.left == 0 &&
- bounds.bottom == 0 && bounds.right == 0)
- {
- portRect = window->portRect;
- bitMapRect = window->portBits.bounds;
-
- bounds.top = portRect.top - bitMapRect.top;
- bounds.left = portRect.left - bitMapRect.left;
- bounds.bottom = portRect.bottom - bitMapRect.top;
- bounds.right = portRect.right - bitMapRect.left;
- }
- return(bounds);
- }
-
- //----------------------------------------------------------------------------------//
- #pragma segment Initialize
- void InitAEHandlers()
- {
- AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,NewAEEventHandlerProc(HandleOpenApp), nil,false);
- AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,NewAEEventHandlerProc(DummyHandler), nil,false);
- AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,NewAEEventHandlerProc(DummyHandler), nil,false);
- AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(HandleQuitApp), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAEClone, NewAEEventHandlerProc(HandleClone), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAEClose, NewAEEventHandlerProc(HandleClose), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAECountElements, NewAEEventHandlerProc(HandleCountElements), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAECreateElement, NewAEEventHandlerProc(HandleCreateElement), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAEDelete, NewAEEventHandlerProc(HandleClose), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAEDoObjectsExist, NewAEEventHandlerProc(HandleDoObjectsExist), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAEGetData, NewAEEventHandlerProc(HandleGetData), kAEGetData, false);
- AEInstallEventHandler(kAECoreSuite, kAEGetDataSize, NewAEEventHandlerProc(HandleGetData), kAEGetDataSize, false);
- AEInstallEventHandler(kAECoreSuite, kAEGetClassInfo, NewAEEventHandlerProc(DummyHandler), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAEGetEventInfo, NewAEEventHandlerProc(DummyHandler), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAEMove, NewAEEventHandlerProc(HandleMove), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAESave, NewAEEventHandlerProc(DummyHandler), nil, false);
- AEInstallEventHandler(kAECoreSuite, kAESetData, NewAEEventHandlerProc(HandleSetData), nil, false);
-
- AEObjectInit();
- AEInstallObjectAccessor(cWindow, typeNull, NewOSLAccessorProc(WindowAccessor), nil, false);
- AEInstallObjectAccessor(cProperty, typeNull, NewOSLAccessorProc(AppPropertyAccessor), nil, false);
- AEInstallObjectAccessor(cProperty, cWindow, NewOSLAccessorProc(WindowPropertyAccessor), nil, false);
- }
-